﻿using PBO.Data;
using PBO.Data.Rnd;
using PBO.Game;
using PBO.Network;
using PBO.Network.Enumerations;
using System;
using System.Collections.Generic;
using System.Linq;

namespace PBO.Game.BattleClass
{
    public partial class Battle
    {
        #region SortPlayerMove

        private void SortPlayerMoves(IEnumerable<PlayerBattleMove> moves)
        {
            SetRandomPriority(moves);

            foreach (var move in moves)
            {
                move.SetPM(this);
                if (move.Move == BattleMove.SwapPokemon)
                {
                    changeList.Add(move);
                }
                else if (move.Move == BattleMove.Attack)
                {
                    atkList.Add(move);
                }
            }
            foreach (var move in atkList)
            {
                var _with1 = move.PM;
                if (move.FocusPunch && _with1.State != PokemonState.Sleep && _with1.State != PokemonState.Freeze && !(_with1.GetSelTrait() == Trait.Truant && _with1.BattleState.traitRaised))
                {
                    log.AppendMsg("EnFocusPunch", _with1.GetNameString());
                    //log.AppendText(_with1.GetNameString() + "正在蓄力"); 
                }
                if (_with1.GetItem() == Item.CustapBerry && atkList.Count > 1)
                    _with1.RaiseItem();
            }

            SortChangeList(changeList);
            SortAttackList(atkList);
        }

        private void SetRandomPriority(IEnumerable<PlayerBattleMove> moves)
        {
            int index = 1;
            foreach (PlayerBattleMove move in moves.GetRandom(_random, moves.Count()))
            {
                move.RandomPriority = index++;
            }
            //List<int> randomList = new List<int>();
            //for (int i = 1; i <= moves.Count; i++)
            //{
            //    randomList.Add(i);
            //}
            //foreach (PlayerBattleMove move in moves)
            //{
            //    int randomIndex = _random.Next(0, randomList.Count);
            //    move.RandomPriority = randomList[randomIndex];
            //    randomList.RemoveAt(randomIndex);
            //}
        }

        private void SortChangeList(List<PlayerBattleMove> list)
        {
            list.Sort(CompareChange);
        }

        private void SortAttackList(List<PlayerBattleMove> list)
        {
            foreach (PlayerBattleMove playerMove in list)
            {
                playerMove.SetPriority(_random);
            }
            list.Sort(CompareAttack);
        }

        private static int CompareChange(PlayerBattleMove move1, PlayerBattleMove move2)
        {
            if (move1 == null && move2 == null)
                return 0;
            if (move1 == null)
                return 1;
            if (move2 == null)
                return -1;
            if (object.ReferenceEquals(move1, move2))
                return 0;
            return move1.RandomPriority.CompareTo(move2.RandomPriority);
        }

        private int CompareAttack(PlayerBattleMove move1, PlayerBattleMove move2)
        {
            if (move1 == null && move2 == null)
                return 0;
            if (move1 == null)
                return 1;
            if (move2 == null)
                return -1;
            if (object.ReferenceEquals(move1, move2))
                return 0;

            double priority1 = 0;
            double priority2 = 0;

            priority1 = move1.GetPriority();
            priority2 = move2.GetPriority();

            if (priority1 != priority2)
            {
                return priority2.CompareTo(priority1);
            }

            if (move1.PM.GetSelTrait() == Trait.Stall && move2.PM.GetSelTrait() == Trait.Stall)
            {
                return move1.PM.Speed.CompareTo(move2.PM.Speed);
            }
            else if (move1.PM.GetSelTrait() == Trait.Stall)
            {
                return 1;
            }
            else if (move2.PM.GetSelTrait() == Trait.Stall)
            {
                return -1;
            }

            if (move1.PM.Speed != move2.PM.Speed)
            {
                if (Ground.TrickRoom)
                    return move1.PM.Speed.CompareTo(move2.PM.Speed);
                return move2.PM.Speed.CompareTo(move1.PM.Speed);
            }
            else
            {
                return move1.RandomPriority.CompareTo(move2.RandomPriority);
            }
        }

        /// <summary>
        /// 计算先制度
        /// </summary>
        public static int CountAtkPriority(Pokemon pm, int moveIndex)
        {
            int priority = 0;
            if (moveIndex != StruggleIndex && pm.CanChooseMove)
                priority = pm.GetSelMove(moveIndex).Priority;
            return priority;
        }

        #endregion
    }
}
